package com.feinno.urcs.group.http.task;

import com.feinno.sip.header.ContentType;
import com.feinno.sip.header.ContributionID;
import com.feinno.sip.header.ConversationID;
import com.feinno.sip.header.extensions.ReferredBy;
import com.feinno.sip.message.SipRequest;
import com.feinno.sip.util.IDUtils;
import com.feinno.threading.Future;
import com.feinno.urcs.content.UrcsMultipartMimeContent;
import com.feinno.urcs.group.GroupConstants;
import com.feinno.urcs.group.http.config.GroupHttpConstant;
import com.feinno.urcs.group.pd.downstream.entity.GroupInvite;
import com.feinno.urcs.group.pd.task.entity.PdGroupInviteMessageArgs;
import com.feinno.urcs.nai.IMPU;
import com.feinno.urcs.sip.UrcsSipFactory;
import com.feinno.urcs.sipservlet.uac.RcsPageModeUAC;
import com.feinno.urcs.sipservlet.uac.RcsUACVisitorAdapter;
import com.feinno.util.Result;
import org.helium.framework.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by wuzhiguo on 15-6-5.
 */
public class PdGroupInviteMessageTask extends PdBaseMessageTask implements Task<PdGroupInviteMessageArgs> {

    private static final Logger LOGGER = LoggerFactory.getLogger(PdGroupInviteMessageTask.class);

    @Override
    public void processTask(PdGroupInviteMessageArgs args) {
        try {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info(String.format("Received Args: %s", args));
            }

            final RcsPageModeUAC uac = createPageModeUAC(args.getBaseGroupMessage());
            final ConversationID conversationID = new ConversationID(args.getBaseGroupMessage().getGroupConversationId());
            final ContributionID contributionID = new ContributionID(IDUtils.createId(8));
            final ReferredBy referredBy = new ReferredBy();
            IMPU inviterIMPU = IMPU.parse(args.getInviterUri());
            referredBy.setAddress(UrcsSipFactory.getAddressFactory().createAddress(inviterIMPU.toUri()));

            uac.accept(new RcsUACVisitorAdapter() {
                @Override
                public void visitorSend(SipRequest request) {
                    super.visitorSend(request);
                    request.setHeader(conversationID);
                    request.setHeader(contributionID);
                    if (referredBy != null) {
                        request.setHeader(referredBy);
                    }
                }
            });

            ContentType contentType = new ContentType("message", "group-invite");
            byte[] content = createContentXml(args);
            final UrcsMultipartMimeContent urcsContent = UrcsMultipartMimeContent.newInstance(contentType, content);
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info(String.format("Create Content Xml: %s", new String(content)));
            }

            Future<Integer> beginFuture = uac.begin();
            beginFuture.addListener((Result<Integer> beginResult) -> {
                try {
                    if (beginResult.getValue() < 200 || beginResult.getValue() >= 300) {
                        LOGGER.error(String.format("UAC Begin Failure.\nresultValue: %s\nArgs: %s", beginResult.getValue(), args));
                        uac.end();
                        return;
                    }

                    Future<Integer> sendFuture = uac.send(urcsContent);
                    sendFuture.addListener((Result<Integer> sendResult) -> {
                        try {
                            if (sendResult.getValue() < 200 || sendResult.getValue() >= 300) {
                                LOGGER.error(String.format("UAC Send Failure.\nresultValue: %s\nArgs: %s", sendResult.getValue(), args));
                                uac.end();
                                return;
                            }

                            if (LOGGER.isInfoEnabled()) {
                                LOGGER.info(String.format("UAC Send Successfully.\nresultValue: %s\nArgs: %s", sendResult.getValue(), args));
                            }

                            uac.end();

                        } catch (Exception ex) {
                            LOGGER.error(String.format("UAC Send Callback Error. Args: %s", args), ex);
                        }
                    });

                } catch (Exception ex) {
                    LOGGER.error(String.format("UAC Begin Callback Error. Args: %s", args), ex);
                    uac.end();
                }
            });

        } catch (Exception ex) {
            LOGGER.error(String.format("process() Error. Received Args: %s", args), ex);
        }
    }

    private byte[] createContentXml(PdGroupInviteMessageArgs args) {
        GroupInvite groupInvite = new GroupInvite();
        groupInvite.setGroupName(args.getBaseGroupMessage().getGroupName());
        groupInvite.setGroupOwner(args.getBaseGroupMessage().getGroupOwnerUri());
        groupInvite.setGroupUri(args.getBaseGroupMessage().getGroupUri());
        groupInvite.setGroupIdentifier(String.format(GroupConstants.PUBLIC_GROUP_IDENTIFIER_TEMPLATE, args.getBaseGroupMessage().getGroupUri()));
        return groupInvite.toXmlByteArray();
    }
}
